一般流程
原始数据:表格、图片、视频、文本、语音、……
特征工程:
模型学习:最核心的部分,学习一个用来预测的映射
所有样本都有类别标记
| 原始数据 | 样本/示例 | 属性/特征 | 标记 |
|---|---|---|---|
| $o_1$ | $(\xv_1, y_1)$ | $\xv_1[1:d]$ | $y_1$ |
| $o_2$ | $(\xv_2, y_2)$ | $\xv_2[1:d]$ | $y_2$ |
| $\vdots$ | $\vdots$ | $\vdots$ | $\vdots$ |
| $o_m$ | $(\xv_m, y_m)$ | $\xv_m[1:d]$ | $y_m$ |
任务类型:
线性回归:用最小二乘求解超定方程组 (方程个数比未知数多)
只有部分样本有类别标记,如何利用其它未标记样本?
| 原始数据 | 样本/示例 | 属性/特征 | 标记 |
|---|---|---|---|
| $o_1$ | $(\xv_1, y_1)$ | $\xv_1[1:d]$ | $y_1$ |
| $\vdots$ | $\vdots$ | $\vdots$ | $\vdots$ |
| $o_l$ | $(\xv_l, y_l)$ | $\xv_m[1:d]$ | $y_l$ |
| $o_{l+1}$ | $(\xv_{l+1}, -)$ | $\xv_{l+1}[1:d]$ | $-$ |
| $\vdots$ | $\vdots$ | $\vdots$ | $\vdots$ |
| $o_{l+u}$ | $(\xv_{l+u}, -)$ | $\xv_{l+u}[1:d]$ | $-$ |
任务类型:
所有样本都没有类别标记
| 原始数据 | 样本/示例 | 属性/特征 | 标记 |
|---|---|---|---|
| $o_1$ | $(\xv_1, -)$ | $\xv_1[1:d]$ | $-$ |
| $o_2$ | $(\xv_2, -)$ | $\xv_2[1:d]$ | $-$ |
| $\vdots$ | $\vdots$ | $\vdots$ | $\vdots$ |
| $o_m$ | $(\xv_m, -)$ | $\xv_m[1:d]$ | $-$ |
任务类型:
米哈尔斯基 等《机器学习:一种人工智能途径》
Machine Learning: An Artificial Intelligence Approach
费根鲍姆 等《人工智能手册》
The Handbook of Artificial Intelligence
多明戈斯 Pedro Domingos
《终极算法》The Master Algorithm
灵魂问题:哪个算法更好?
| 约会次序 | 约会时间 | 约会方式 | 当天温度 | 当天电视 | 答应约会 |
|---|---|---|---|---|---|
| 1 | 周末 | 吃饭 | 暖和 | 不好看 | 否 |
| 2 | 周末 | 逛街 | 暖和 | 好看 | 是 |
| 3 | 周末 | 逛街 | 暖和 | 不好看 | 是 |
| 4 | 周末 | 逛街 | 炎热 | 好看 | 否 |
| 5 | 周末 | 逛街 | 炎热 | 不好看 | ? |
| 约会次序 | 约会时间 | 约会方式 | 当天温度 | 当天电视 | 答应约会 |
|---|---|---|---|---|---|
| 1 | 周末 | 吃饭 | 暖和 | 不好看 | 否 |
| 2 | 周末 | 逛街 | 暖和 | 好看 | 是 |
| 3 | 周末 | 逛街 | 暖和 | 不好看 | 是 |
| 4 | 周末 | 逛街 | 炎热 | 好看 | 否 |
| 5 | 周末 | 逛街 | 炎热 | 不好看 | ? |
用“若……且……则……”形式的合取规则尽可能地覆盖正样本
$(\text{方式} = \text{逛街}) \wedge (\text{温度} = \text{暖和}) \rightarrow (\text{约会} = \text{是})$
| 约会次序 | 约会时间 | 约会方式 | 当天温度 | 当天电视 | 答应约会 |
|---|---|---|---|---|---|
| 1 | 周末 | 吃饭 | 暖和 | 不好看 | 否 |
| 2 | 周末 | 逛街 | 暖和 | 好看 | 是 |
| 3 | 周末 | 逛街 | 暖和 | 不好看 | 是 |
| 4 | 周末 | 逛街 | 炎热 | 好看 | 否 |
| 5 | 周末 | 逛街 | 炎热 | 不好看 | ? |
用带阈值的线性函数拟合数据
$\sgn(w_0 + w_1 \cdot \text{次序} + \cdots + w_5 \cdot \text{电视}) \rightarrow \{\text{是}, \text{否}\}$
| 约会次序 | 约会时间 | 约会方式 | 当天温度 | 当天电视 | 答应约会 |
|---|---|---|---|---|---|
| 1 | 周末 | 吃饭 | 暖和 | 不好看 | 否 |
| 2 | 周末 | 逛街 | 暖和 | 好看 | 是 |
| 3 | 周末 | 逛街 | 暖和 | 不好看 | 是 |
| 4 | 周末 | 逛街 | 炎热 | 好看 | 否 |
| 5 | 周末 | 逛街 | 炎热 | 不好看 | ? |
利用贝叶斯公式求后验概率
$\Pr (\text{约会}|\text{次序},\ldots,\text{电视}) = \frac{\Pr (\text{次序},\ldots,\text{电视}|\text{约会}) \Pr (\text{约会}) \qquad \quad}{\Pr (\text{次序},\ldots,\text{电视}) \qquad}$
| 约会次序 | 约会时间 | 约会方式 | 当天温度 | 当天电视 | 答应约会 |
|---|---|---|---|---|---|
| 1 | 周末 | 吃饭 | 暖和 | 不好看 | 否 |
| 2 | 周末 | 逛街 | 暖和 | 好看 | 是 |
| 3 | 周末 | 逛街 | 暖和 | 不好看 | 是 |
| 4 | 周末 | 逛街 | 炎热 | 好看 | 否 |
| 5 | 周末 | 逛街 | 炎热 | 不好看 | ? |
引入相似度函数$s(\cdot, \cdot)$和样本权重$\alpha$
$\sgn(\alpha_1 \cdot s(\xv_1, \xv_5) \cdot y_1 + \cdots + \alpha_4 \cdot s(\xv_4, \xv_5) \cdot y_4) \rightarrow \{\text{是}, \text{否}\}$
给定模型$f$、数据集$D = \{ (\xv_i, y_i) \}_{i \in [m]}$
均方误差 (mean squared error, MSE)
$$ \begin{align*} E_D (f) = \frac{1}{m} \sum_{i \in [m]} (f(\xv_i) - y_i)^2 \end{align*} $$
from sklearn.metrics import mean_squared_error y_true = [3, -0.5, 2, 7] y_pred = [2.5, 0.0, 2, 8] mean_squared_error(y_true, y_pred) # MSE 0.375 mean_squared_error(y_true, y_pred, squared=False) # RMSE 0.6123724356957945
给定模型$f$、数据集$D = \{ (\xv_i, y_i) \}_{i \in [m]}$
错误率 (error rate)、精度 (accuracy)
$$ \begin{align*} E_D (f) = \frac{1}{m} \sum_{i \in [m]} \Ibb (f(\xv_i) \ne y_i), ~ \acc(f;D) = 1 - E_D (f) \end{align*} $$
from sklearn.metrics import accuracy_score y_true = [0, 1, 2, 3] y_pred = [0, 2, 1, 3] accuracy_score(y_true, y_pred) # 百分比 0.5 accuracy_score(y_true, y_pred, normalize=False) # 正确分类的个数 2
二分类结果的混淆矩阵 (confusion matrix)
| 预测 正例 | 实际 负例 | |
|---|---|---|
| 真实 正例 | $\TP$ (真正例) | $\FN$ (假反例) |
| 真实 负例 | $\FP$ (假正例) | $\TN$ (真反例) |
查准率 (precision):预测的约会中有多少比例真的约会了
查全率 (recall):所有的约会中有多少比例被预测出来了
$$ \begin{align*} & \mathrm{precision} = \frac{\TP}{\TP + \FP}, \quad \mathrm{recall} = \frac{\TP}{\TP + \FN} \\[4pt] & \mathrm{F1} = \frac{2 \cdot \mathrm{Precision} \cdot \mathrm{Recall}}{\mathrm{Precision} + \mathrm{Recall}} = \frac{2 \cdot \TP}{\text{样本总数} + \TP - \TN \quad} \end{align*} $$
from sklearn.metrics import confusion_matrix from sklearn.metrics import precision_score, recall_score, f1_score y_true = [1, 1, 0, 0, 1, 0, 1, 0] y_pred = [0, 1, 0, 1, 1, 1, 1, 0] cm = confusion_matrix(y_true, y_pred, labels=[1,0]) cm array([[3, 1], [2, 2]]) tp, fn, fp, tn = cm.ravel() tp, fn, fp, tn (3, 1, 2, 2) precision_score(y_true, y_pred) 0.6 recall_score(y_true, y_pred) 0.75 f1_score(y_true, y_pred) 0.6666666666666665
选择宗旨:在未知数据上表现好,即泛化 (generalization) 好
特征空间$\Xcal \subset \Rbb^d$,标记空间$\Ycal \subset \Rbb$,$\Xcal \times \Ycal$上的未知分布$\Dcal$
给定模型$f$,训练数据集$D = \{ (\xv_i, y_i) \}_{i \in [m]}$,其中$(\xv_i, y_i) \overset{\mathrm{iid}}{\sim} \Dcal$
经验 (empirical) 均方误差 (训练数据集上的均方误差)
$$ \begin{align*} E_D (f) = \frac{1}{m} \sum_{i \in [m]} (f(\xv_i) - y_i)^2 \end{align*} $$
泛化均方误差,可通过测试 (test) 数据集来近似估计
$$ \begin{align*} E_{\Dcal} (f) = \Ebb_{(\xv,y) \sim \Dcal} [(f(\xv) - y)^2] = \Ebb_{D \sim \Dcal^m} [E_D (f)] \end{align*} $$
选择宗旨:在未知数据上表现好,即泛化 (generalization) 好
特征空间$\Xcal \subset \Rbb^d$,标记空间$\Ycal$,$\Xcal \times \Ycal$上的未知分布$\Dcal$
给定模型$f$,训练数据集$D = \{ (\xv_i, y_i) \}_{i \in [m]}$,其中$(\xv_i, y_i) \overset{\mathrm{iid}}{\sim} \Dcal$
经验 (empirical) 错误率 (训练数据集上的错误率)
$$ \begin{align*} E_D (f) = \frac{1}{m} \sum_{i \in [m]} \Ibb (f(\xv_i) \ne y_i) \end{align*} $$
泛化错误率,可通过测试数据集来近似估计
$$ \begin{align*} E_{\Dcal} (f) = \Ebb_{(\xv,y) \sim \Dcal} [\Ibb(f(\xv) \ne y)] = \Ebb_{D \sim \Dcal^m} [E_D (f)] \end{align*} $$
训练集:余弦函数中随机采样的$30$个点加上$0.1$的随机噪声
学习算法:$n$阶多项式回归,$n=1$即为线性回归
$$ \begin{align*} \min_{w_j} ~ g (w_j) = \frac{1}{2} \sum_{i \in [30]} \left( \sum_{j=0}^n w_j x_i^j - y_i \right)^2 \end{align*} $$
其中$w_0, w_1, \ldots, w_n$为待求参数
目标函数$g$关于$w_j$的偏导数为
$$ \begin{align*} \frac{\partial g}{\partial w_j} = \sum_{i \in [30]} \left( \sum_{j=0}^n w_j x_i^j - y_i \right) x_i^j \end{align*} $$
左图:1 阶多项式欠拟合 (underfitting),经验均方误差很大
中图:4 阶多项式拟合地最好,最贴近真实模型
右图:30 阶多项式过拟合 (overfitting),经验均方误差为零
事先选定合适的模型 (归纳偏倚) 很重要!
从训练集中随机选择一部分样本作为验证集 (validation set)
据此比较多个候选模型的性能
交叉验证 (cross validation):将训练集平均分为$n$份,每轮
迭代$n$轮取平均,据此比较多个候选模型的性能
以回归问题为例,对任意样本$(\xv,y) \sim \Dcal$,均方误差可分解为
$$ \begin{align*} (f (\xv) & - y)^2 = (f (\xv) - \Ebb [y|\xv] + \Ebb [y|\xv] - y)^2 \\ & = (f (\xv) - \Ebb [y|\xv])^2 + (\Ebb [y|\xv] - y)^2 + 2 (f (\xv) - \Ebb [y|\xv]) (\Ebb [y|\xv] - y) \end{align*} $$
其中条件期望$\Ebb [y|\xv]$与$y$无关,对交叉项有
$$ \begin{align*} \Ebb_{(\xv,y)} & [(f (\xv) - \Ebb [y|\xv]) (\Ebb [y|\xv] - y) ] \\ & = \iint (f (\xv) - \Ebb [y|\xv]) (\Ebb [y|\xv] - y) \Pr(\xv, y) \diff \xv \diff y \\ & = \int (f (\xv) - \Ebb [y|\xv]) \left( \int (\Ebb [y|\xv] - y) \Pr(\xv, y) \diff y \right) \diff \xv \\ & = \int (f (\xv) - \Ebb [y|\xv]) \underbrace{ ( \Ebb [y|\xv] \Pr(\xv) - \Pr(\xv) \overbrace{ \class{yellow}{\int y \Pr(y|\xv) \diff y}}^{=~\Ebb [y|\xv]} )}_{=~0} \diff \xv = 0 \end{align*} $$
$$ \begin{align*} \Ebb_{(\xv,y)} [(f (\xv) - y)^2] & = \Ebb_{(\xv,y)} [(\overbrace{f (\xv) - \Ebb [y|\xv]}^{\mathrm{independent~of~}y})^2] + \overbrace{\Ebb_{(\xv,y)} [(\Ebb [y|\xv] - y)^2]}^{\mathrm{noise~of~}y} \\ & = \Ebb_{\xv} [(f (\xv) - \Ebb [y|\xv])^2] + \noise \end{align*} $$
第二项标记中的噪声是问题所固有的,与模型$f$的选择无关
根据第一项,使得泛化均方误差最小的$f^\star (\xv) = \Ebb [y|\xv]$
将数据集$D$的随机性也考虑进来,注意$\noise$与$D$无关,故
$$ \begin{align*} E = \Ebb_D \Ebb_{(\xv,y)} [(f_D (\xv) & - y)^2] = \Ebb_{\xv} \Ebb_D [(f_D (\xv) - \Ebb [y|\xv])^2] + \noise \end{align*} $$
泛化均方误差$E = \Ebb_{\xv} \Ebb_D [(f_D (\xv) - \Ebb [y|\xv])^2] + \noise$
引入$\xv$的期望预测$\Ebb_D [f_D (\xv)]$,易知有分解
$$ \begin{align*} & (f_D (\xv) - \Ebb [y|\xv])^2 = (f_D (\xv) - \Ebb_D [f_D (\xv)] + \Ebb_D [f_D (\xv)] - \Ebb [y|\xv])^2 \\ & = (f_D (\xv) - \Ebb_D [f_D (\xv)])^2 + (\Ebb_D [f_D (\xv)] - \Ebb [y|\xv])^2 \\ & \qquad + 2 (f_D (\xv) - \Ebb_D [f_D (\xv)]) (\Ebb_D [f_D (\xv)] - \Ebb [y|\xv]) \end{align*} $$
注意$\Ebb_D [f_D (\xv)]$与$D$无关,对交叉项有
$$ \begin{align*} \Ebb_D & [(f_D (\xv) - \Ebb_D [f_D (\xv)]) (\overbrace{\Ebb_D [f_D (\xv)] - \Ebb [y|\xv]}^{\mathrm{independent~of~}D})] \\ & = (\Ebb_D [f_D (\xv)] - \Ebb [y|\xv]) \underbrace{\Ebb_D [f_D (\xv) - \Ebb_D [f_D (\xv)]]}_{=~0} = 0 \end{align*} $$
$$ \begin{align*} E & = \Ebb_{\xv} \Ebb_D [(f_D (\xv) - \Ebb_D [f_D (\xv)])^2] + \Ebb_{\xv} \Ebb_D [(\overbrace{\Ebb_D [f_D (\xv)] - \Ebb [y|\xv]}^{\mathrm{independent~of~}D})^2] + \noise \\ & = \underbrace{\Ebb_{\xv} \Ebb_D [(f_D (\xv) - \Ebb_D [f_D (\xv)])^2]}_{\variance} + \underbrace{\Ebb_{\xv} [(\Ebb_D [f_D (\xv)] - \Ebb [y|\xv])^2]}_{\bias^2} + \noise \end{align*} $$
综上,泛化均方误差的偏差方差分解为
$$ \begin{align*} \Ebb_{(\xv,y)} \Ebb_D [(f_D (\xv) - y)^2] = \bias^2 + \variance + \noise \end{align*} $$
训练不足时,模型拟合能力不强,数据集扰动的影响不大
训练程度加深后,模型对数据集扰动很敏感,方差占主导
一般流程
原始数据:表格、图片、视频、文本、语音、……
特征工程:
模型学习:最核心的部分,学习一个用来预测的映射
词袋模型 (bag-of-words):文本是单词的集合,单词独立无序
from sklearn.feature_extraction.text import CountVectorizer import pandas as pd document1 = "I have a pen, I have an apple, apple pen." document2 = "I have a pen, I have pineapple, pineapple pen." cv = CountVectorizer(lowercase=False, token_pattern='\w+', binary=True) model = cv.fit_transform([document1, document2]) pd.DataFrame(model.toarray(), columns=cv.get_feature_names_out())
| 词典 | I | a | an | apple | have | pen | pineapple |
|---|---|---|---|---|---|---|---|
| 文本 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
| 文本 2 | 1 | 1 | 0 | 0 | 1 | 1 | 1 |
词袋模型 (bag-of-words):文本是单词的集合,单词独立无序
from sklearn.feature_extraction.text import CountVectorizer import pandas as pd document1 = "I have a pen, I have an apple, apple pen." document2 = "I have a pen, I have pineapple, pineapple pen." cv = CountVectorizer(lowercase=False, token_pattern='\w+') model = cv.fit_transform([document1, document2]) pd.DataFrame(model.toarray(), columns=cv.get_feature_names_out())
| 词典 | I | a | an | apple | have | pen | pineapple |
|---|---|---|---|---|---|---|---|
| 文本 1 | 2 | 1 | 1 | 2 | 2 | 2 | 0 |
| 文本 2 | 2 | 1 | 0 | 0 | 2 | 2 | 2 |
词频 - 逆文本频率特征:对当前文本重要的单词必然
tf = 单词在当前文本中出现的次数 / 当前文本的总词数
idf = ln ((全部文本数 + C) / (包含该词的总文本数 + C)) + 1
tf - idf 特征 = normalize (tf × idf),即将 tf 和 idf 相乘后再标准化
from sklearn.feature_extraction.text import TfidfVectorizer import pandas as pd document1 = "I have a pen, I have an apple, apple pen." document2 = "I have a pen, I have pineapple, pineapple pen." tv = TfidfVectorizer(lowercase=False, token_pattern='\w+', norm='l1', smooth_idf=False) # l1归一化 idf不平滑 model = tv.fit_transform([document1, document2]) pd.DataFrame(model.toarray(), columns=cv.get_feature_names_out())
| 词典 | I | a | an | apple | have | pen | pineapple |
|---|---|---|---|---|---|---|---|
| tf | 2 / 10 | 1 / 10 | 1 / 10 | 2 / 10 | 2 / 10 | 2 / 10 | 0 |
| 2 / 9 | 1 / 9 | 0 | 0 | 2 / 9 | 2 / 9 | 2 / 9 | |
| idf | ln (1) + 1 | ln (1) + 1 | ln (2) + 1 | ln (2) + 1 | ln (1) + 1 | ln (1) + 1 | ln (2) + 1 |
| tf - idf | 0.165571 | 0.082785 | 0.140168 | 0.280335 | 0.165571 | 0.165571 | 0.000000 |
| 0.192561 | 0.096281 | 0.000000 | 0.000000 | 0.192561 | 0.192561 | 0.326035 |
| 约会次序 | 约会时间 | 约会方式 | 当天温度 | 当天电视 | 答应约会 |
|---|---|---|---|---|---|
| 1 | 周末 | 吃饭 | 暖和 | 不好看 | 是 |
| 2 | 周末 | 逛街 | 凉爽 | 好看 | 是 |
| 3 | 周末 | 看电影 | 暖和 | 不好看 | 否 |
| 4 | 周末 | 逛街 | 炎热 | 好看 | 否 |
import numpy as np from sklearn.preprocessing import LabelBinarizer, OneHotEncoder X = np.array([ [1, '周末', '吃饭', '暖和', '不好看'], [2, '周末', '逛街', '凉爽', '好看'], [3, '周末', '看电影', '暖和', '不好看'], [4, '周末', '逛街', '炎热', '好看'],]) y = np.array(['是', '是', '否', '否']) LabelBinarizer().fit_transform(y).squeeze() # 标记二值化 [1 1 0 0] enc = OneHotEncoder() enc.fit_transform(X).toarray() # 对5个类别特征采用独热编码 [[1., 0., 0., 0., 1., 1., 0., 0., 0., 1., 0., 1., 0.], [0., 1., 0., 0., 1., 0., 0., 1., 1., 0., 0., 0., 1.], [0., 0., 1., 0., 1., 0., 1., 0., 0., 1., 0., 1., 0.], [0., 0., 0., 1., 1., 0., 0., 1., 0., 0., 1., 0., 1.]] enc.get_feature_names_out() # 独热编码对应的原始特征 ['x0_1', 'x0_2', 'x0_3', 'x0_4', 'x1_周末', 'x2_吃饭', 'x2_看电影', 'x2_逛街', 'x3_凉爽', 'x3_暖和', 'x3_炎热', 'x4_不好看', 'x4_好看']
| 约会次序 | 约会时间 | 约会方式 | 当天温度 | 当天电视 | 答应约会 |
|---|---|---|---|---|---|
| 1 | 周末 | 吃饭 | 25 | 不好看 | 是 |
| 2 | 周末 | 逛街 | - | 好看 | 是 |
| 3 | 周末 | - | 28 | 不好看 | 否 |
| 4 | 周末 | 逛街 | 36 | 好看 | 否 |
删除:直接删除有特征缺失的样本,简单粗暴,信息损失
补全:
import numpy as np from sklearn.experimental import enable_iterative_imputer from sklearn.impute import SimpleImputer, IterativeImputer X = np.array([ [1, '周末', '吃饭', 25, '不好看'], [2, '周末', '逛街', np.nan, '好看'], [3, '周末', '-', 29, '不好看'], [4, '周末', '逛街', 36, '好看'],]) imp_mean = SimpleImputer(strategy='mean') imp_mean.fit_transform(X[:, 3:4]) # 用均值填充 [[25.], [30.], [29.], [36.]] imp_median = SimpleImputer(strategy='median') imp_median.fit_transform(X[:, 3:4]) # 用中位数填充 [[25.], [29.], [29.], [36.]]
import numpy as np from sklearn.impute import SimpleImputer X = np.array([ [1, '周末', '吃饭', 25, '不好看'], [2, '周末', '逛街', np.nan, '好看'], [3, '周末', '-', 29, '不好看'], [4, '周末', '逛街', 36, '好看'],]) imp_frequent = SimpleImputer(missing_values='-', strategy='most_frequent') imp_frequent.fit_transform(X[:, 2:3].astype('object')) # 用众数填充 [['吃饭'], ['逛街'], ['逛街'], ['逛街']] imp_iter = IterativeImputer() imp_iter.fit_transform(X[:, [0,3]]) # 回归器默认采用BayesianRidge [[ 1. , 25. ], [ 2. , 27.86309709], [ 3. , 29. ], [ 4. , 36. ]]
也称归一化,旨在消除不同特征间的量纲影响
离差标准化:将原始特征线性变换到 [0, 1] 区间
$$ \begin{align*} x \leftarrow \frac{x - x_\min}{x_\max - x_\min} \in [0,1] \end{align*} $$
最大值标准化:除以该特征的绝对值最大值
$$ \begin{align*} x \leftarrow \frac{x}{\max_{i \in [m]} |x_i|} \in [-1,1] \end{align*} $$
标准差标准化:经过处理的特征近似符合标准正态分布$\Ncal(0,1)$
$$ \begin{align*} x \leftarrow \frac{x - \mu}{\sigma}, \quad x \leftarrow \frac{x - x_{\text{median}}}{\sum_{i \in [m]} |x_i - x_{\text{median}}| / m} \end{align*} $$
import numpy as np from sklearn.preprocessing import MinMaxScaler, MaxAbsScaler X = np.array([ [1, '周末', '吃饭', 25, '不好看'], [2, '周末', '逛街', 28, '好看'], [3, '周末', '看电影', 29, '不好看'], [4, '周末', '逛街', 36, '好看'],]) MinMaxScaler().fit_transform(X[:, [0,3]]) # 最大值变成1 同时 最小值变成0 [[0. , 0. ], [0.33333333, 0.27272727], [0.66666667, 0.36363636], [1. , 1. ]] MaxAbsScaler().fit_transform(X[:, [0,3]]) # 最大值变成1 [[0.25 , 0.69444444], [0.5 , 0.77777778], [0.75 , 0.80555556], [1. , 1. ]]
import numpy as np from sklearn.preprocessing import scale X = np.array([ [1, '周末', '吃饭', 25, '不好看'], [2, '周末', '逛街', 28, '好看'], [3, '周末', '看电影', 29, '不好看'], [4, '周末', '逛街', 36, '好看'],]) x = scale(X[:, [0,3]]) x [[-1.34164079, -1.11631261], [-0.4472136 , -0.3721042 ], [ 0.4472136 , -0.12403473], [ 1.34164079, 1.61245155]] x.mean(axis=0) # 均值为0 [0. 0.] x.std(axis=0) # 标准差为1 [1. 1.]
模型学习前的最后一步,亦有将该步与模型学习融合的做法
当部分特征冗余甚至有害时,挑选或生成有用的特征子集
当特征稀缺时,利用现有特征构造新的特征
过滤低方差特征,尤其是那些在所有样本上取值均相同的特征
import numpy as np from sklearn.feature_selection import VarianceThreshold X = np.array([ # 对约会数据集的5个离散类别特征采用了独热编码 [1., 0., 0., 0., 1., 1., 0., 0., 0., 1., 0., 1., 0.], [0., 1., 0., 0., 1., 0., 0., 1., 1., 0., 0., 0., 1.], [0., 0., 1., 0., 1., 0., 1., 0., 0., 1., 0., 1., 0.], [0., 0., 0., 1., 1., 0., 0., 1., 0., 0., 1., 0., 1.]]) X.shape (4, 13) # 第5列由特征“约会时间”而来 四个样本都取值“周末” 独热编码后都是1 方差为0 XX = VarianceThreshold(threshold=0.01).fit_transform(X) [[1., 0., 0., 0., 1., 0., 0., 0., 1., 0., 1., 0.], [0., 1., 0., 0., 0., 0., 1., 1., 0., 0., 0., 1.], [0., 0., 1., 0., 0., 1., 0., 0., 1., 0., 1., 0.], [0., 0., 0., 1., 0., 0., 1., 0., 0., 1., 0., 1.]] XX.shape (4, 12)